<?php

/**
 * 网银在线支付接口
 */
class PaypalPay extends Pay {

    public $config = array();
    private $gateway = 'https://www.paypal.com/cgi-bin/webscr?';

    public function __construct($config = array()) {
        $this->config = $config;
    }

    public function setup() {
        $modules = array();
        $modules['pay_name'] = 'Paypal';
        $modules['pay_code'] = 'Paypal';
        $modules['pay_desc'] = 'Paypal';
        $modules['is_cod'] = '0';
        $modules['is_online'] = '1';
        $modules['author'] = 'Mr.Wang';
        $modules['website'] = 'http://www.Paypal.com';
        $modules['version'] = '1.0.0';
        $modules['config'] = array(
        );
        return $modules;
    }

    /**
     * 生成订单
     * @return string 
     */
    public function pay_get(&$params) {
        $pp_info = array(); // 初始化准备提交到Paypal的数据
        $pp_info['cmd'] = '_xclick'; // 告诉Paypal，我的网站是用的我自己的购物车系统
        $pp_info['business'] = $this->config['account']; // 告诉paypal，我的（商城的商户）Paypal账号，就是这钱是付给谁的
        $pp_info['item_name'] = "{$this->config['pay_sn']}"; // 用户将会在Paypal的支付页面看到购买的是什么东西，只做显示，没有什么特殊用途，如果是多件商品，则直接告诉用户，只支付某个订单就可以了
        $pp_info['amount'] = format_price($this->config['pay_price']); // 告诉Paypal，我要收多少钱
        $pp_info['currency_code'] = 'USD'; // 告诉Paypal，我要用什么货币。这里需要注意的是，由于汇率问题，如果网站提供了更改货币的功能，那么上面的amount也要做适当更改，paypal是不会智能的根据汇率更改总额的
        $pp_info['return'] = $this->config['return_url_show']; // 当用户成功付款后paypal会将用户自动引导到此页面。如果为空或不传递该参数，则不会跳转
        $pp_info['invoice'] = $this->config['pay_sn'];
        $pp_info['charset'] = 'utf-8';
        $pp_info['no_shipping'] = '1';
        $pp_info['no_note'] = '1';
        $pp_info['cancel_return'] = $this->config['return_url_cancel']; // 当跳转到paypal付款页面时，用户又突然不想买了。则会跳转到此页面
        $pp_info['notify_url'] = $this->config['return_url_hide']; // Paypal会将指定 invoice 的订单的状态定时发送到此URL(Paypal的此操作，是paypal的服务器和我方商城的服务器点对点的通信，用户感觉不到）
        $pp_info['rm'] = '2';

        $button = $this->buildRequestForm($this->gateway, "get", $pp_info, L('PAY_NOW'));
        return $button;
    }

    /**
     * 确认订单
     * @return boolean 
     */
    public function pay_confirm(&$params) {
        // 由于这个文件只有被Paypal的服务器访问，所以无需考虑做什么页面什么的，这个页面不是给人看的，是给机器看的
        $pay_id = (int) $_GET['pay_id'];
        //$order_info = D('Order')->getOrderDetail($order_id);
        // 由于该URL不仅仅只有Paypal的服务器能访问，其他任何服务器都可以向该方法发起请求。所以要判断请求发起的合法性，也就是要判断请求是否是paypal官方服务器发起的
        // 拼凑 post 请求数据
        $req = 'cmd=_notify-validate'; // 验证请求

        if (empty($_POST)) {
            if ($_REQUEST['st'] == 'Completed') {
                return reStatus(true, "Success", "fail");
            } else {
                return reStatus(false, "fail", "fail");
            }
        }

        unset($_POST['_URL_']);
        unset($_POST['payMode']);
        unset($_POST['payAdmin']);
        unset($_POST['hide']);
        unset($_POST['pay_id']);
        foreach ($_POST as $k => $v) {
            $v = iconv("UTF-8", "GBK", $v);
            $v = urlencode(stripslashes($v));
            $req .= "&{$k}={$v}";
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'http://www.paypal.com/cgi-bin/webscr');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        $res = curl_exec($ch);
        curl_close($ch);
        if ($res) {
            // 本次请求是否由Paypal官方的服务器发出的请求
            if (strcmp($res, 'VERIFIED') == 0) {
                /**
                 * 判断订单的状态
                 * 判断订单的收款人
                 * //判断订单金额 $_POST['mc_gross']
                 * 判断货币类型
                 */
                if (($_POST['payment_status'] != 'Completed' && $_POST['payment_status'] != 'Pending') OR ($_POST['receiver_email'] != $this->config['account']) OR ('USD' != $_POST['mc_currency'])) {
                    // 如果有任意一项成立，则终止执行。由于是给机器看的，所以不用考虑什么页面。直接输出即可
                    return reStatus(false, "Error", "fail");
                } else {// 如果验证通过，则证明本次请求是合法的
                    $param = array(
                        "pay_id" => $pay_id,
                        "pay_sn" => $_POST['invoice'],
                        "price" => format_int(intval($_POST['mc_gross'] * 100)),
                    );
                    service("Pay")->payPrice($param);
                    return reStatus(true, "Success", "success");
                }
            } else {
                return reStatus(false, "Failed", "fail");
            }
        }
        return reStatus(false, "Failed", "fail");
    }

}
